package org.scboy.rbac.service.imp;

import java.util.Date;
import java.util.List;

import org.scboy.coobi.sql.factory.EntityFactory;
import org.scboy.rbac.dao.RbacMenusDao;
import org.scboy.rbac.dao.RbacResourceMenuDao;
import org.scboy.rbac.dao.RbacSystemDao;
import org.scboy.rbac.service.MenuService;
import org.scboy.utils.entitys.coobi.Model;
import org.scboy.utils.entitys.coobi.Page;
import org.scboy.utils.enums.coobi.OrderType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.hutool.core.lang.UUID;

/**
 * 
 * 菜单业务类
 * @author yanghao
 *
 */
@Service
public class MenuServiceImp implements MenuService {

	@Autowired
	EntityFactory factory;
	
	/**
	 * 分页查询菜单
	 * 
	 * @param model
	 *            查询参数
	 * @param limit
	 *            分页参数
	 * @return
	 */
	@Override
	public Page page(Model model) {
		RbacMenusDao dao=factory.getDao(RbacMenusDao.class);
		model.orderBy("menuSort");
		return dao.page(model);
	}

	/**
	 * 新增菜单
	 * 
	 * @param model
	 *            菜单Model
	 * @return
	 */
	@Override
	public boolean add(Model model) {
		RbacMenusDao dao=factory.getDao(RbacMenusDao.class);
		model.add("id", UUID.randomUUID().toString());
		Model maxModel=dao.maxIndex(model.getString("parentId"));
		Integer menuSort =0; 
		if (maxModel != null && maxModel.getInt("menuSort")!=null) {
			menuSort =  maxModel.getInt("menuSort")+1;
		}
		
		//处理路径问题
		String menuPath=model.getString("menuPath");
		String menuComponent=model.getString("menuComponent");
		if("#".equals(menuComponent) || "##".equals(menuComponent)) {
			if(menuPath.indexOf("/")!=0) {
				model.add("menuPath","/"+menuPath);
			}
		}else if(!"root".equals(model.getString("parentId")) && menuPath.indexOf("/")==0) {
			model.add("menuPath",menuPath.substring(1));
		}else if("root".equals(model.getString("parentId")) && !menuPath.startsWith("/")){
			model.add("menuPath","/"+menuPath);
		}
		
		model.add("menuSort", menuSort);
		model.add("addTime", new Date());
		model.add("editTime", new Date());
		int result = dao.insert(model);
		if (result > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 删除菜单
	 * 
	 * @param id
	 *            菜单ID
	 * @return
	 */
	@Override
	@Transactional
	public boolean delete(String id) {
		RbacMenusDao dao=factory.getDao(RbacMenusDao.class);
		RbacResourceMenuDao resourceDao=factory.getDao(RbacResourceMenuDao.class);
		// 删除菜单资源关联
		resourceDao.delete(Model.create().add("menuId", id));
		int result = dao.delete(Model.create().add("id", id));
		if (result > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 更新菜单
	 * 
	 * @param model
	 *            菜单Model
	 * @return
	 */
	@Override
	public boolean update(Model model) {
		RbacMenusDao dao=factory.getDao(RbacMenusDao.class);
		
		//处理路径问题
		String menuPath=model.getString("menuPath");
		String menuComponent=model.getString("menuComponent");
		if("#".equals(menuComponent) || "##".equals(menuComponent)) {
			if(menuPath.indexOf("/")!=0) {
				model.add("menuPath","/"+menuPath);
			}
		}else if(!"root".equals(model.getString("parentId")) && menuPath.indexOf("/")==0) {
			model.add("menuPath",menuPath.substring(1));
		}else if("root".equals(model.getString("parentId")) && !menuPath.startsWith("/")){
			model.add("menuPath","/"+menuPath);
		}
		
		model.add("editTime", new Date());
		int result = dao.update(model,
				Model.create().add("id", model.getString("id")));
		if (result > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 启用禁用菜单
	 * 
	 * @param id
	 *            菜单ID
	 * @return
	 */
	@Override
	public boolean checkState(String id) {
		RbacMenusDao dao=factory.getDao(RbacMenusDao.class);
		Model model = get(id);
		if (model == null) {
			return false;
		}
		model.add("menuAction", !model.getBoolean("menuAction"));
		int resultCount = dao.update(model);
		if (resultCount > 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 根据菜单ID获取菜单信息
	 * 
	 * @param id
	 *            菜单ID
	 * @return
	 */
	@Override
	public Model get(String id) {
		RbacMenusDao dao=factory.getDao(RbacMenusDao.class);
		return dao.get(Model.create().add("id", id));
	}

	@Override
	public List<Model> list(String parentId, String sysId) {
		RbacMenusDao dao=factory.getDao(RbacMenusDao.class);
		Model model = new Model();
		model.add("parentId", parentId);
		model.add("sysId", sysId);
		return dao.select(model);
	}

	@Override
	public List<Model> listAll(String sysId) {
		RbacMenusDao dao=factory.getDao(RbacMenusDao.class);
		Model model = new Model();
		model.add("sysId", sysId);
		return dao.select(model);
	}

	@Override
	@Transactional
	public boolean sort(String id, int type) {
		RbacMenusDao dao=factory.getDao(RbacMenusDao.class);
		Model menuModel=dao.get(Model.create().add("id", id));
		Model lastMenu=null;
		//降序
		if(type==0) {
			//查询下面一个菜单
			lastMenu=dao.get(Model.create().GT("menuSort", menuModel.getInt("menuSort")).add("parentId", menuModel.get("parentId")).orderBy("menuSort"));
		}else {
			//升序
			lastMenu=dao.get(Model.create().LT("menuSort", menuModel.getInt("menuSort")).add("parentId", menuModel.get("parentId")).orderBy("menuSort",OrderType.DESC));
		}
		if(lastMenu!=null) {
			dao.update(Model.create().add("menuSort", lastMenu.getInt("menuSort")),Model.create().add("id", id));
			dao.update(Model.create().add("menuSort", menuModel.getInt("menuSort")),Model.create().add("id", lastMenu.getString("id")));
		}
		return true;
	}

	@Override
	public List<Model> tree() {
		RbacSystemDao systemDao=factory.getDao(RbacSystemDao.class);
		List<Model> systems=systemDao.select(Model.create().orderBy("sysSort"));
		for (Model data : systems) {
			data.add("type", "system");
			List<Model> children= menuTree(data.getString("id"), "root");
			if(children.size()>0) {
				data.add("children", children);
			}
		}
		return systems;
	}
	
	
	public List<Model> menuTree(String sysId,String parentId){
		RbacMenusDao dao = factory.getDao(RbacMenusDao.class);
		List<Model> datas = dao.select(Model.create().add("sysId", sysId).add("parentId", parentId).orderBy("menuSort"));
		for (Model data : datas) {
			data.add("type", "menu");
			List<Model> children= menuTree(sysId, data.getString("id"));
			if(children.size()>0) {
				data.add("children", children);
			}
		}
		return datas;
	}

	@Override
	public List<Model> childs(String sysId, String parentId) {
		RbacMenusDao dao = factory.getDao(RbacMenusDao.class);
		List<Model> datas = dao.select(Model.create().add("sysId", sysId).add("parentId", parentId).orderBy("menuSort"));
		for (Model data : datas) {
			data.add("type", "menu");
			long count= dao.count(Model.create().add("sysId", sysId).add("parentId", data.getString("id")));
			if(count>0) {
				data.add("isLeaf", false);
				data.add("isParent", true);
			}else {
				data.add("isLeaf", true);
				data.add("isParent", false);
			}
		}
		return datas;
	}

}
